using System;
using System.Collections.Generic;
using System.IO;
using System.Globalization;
using System.Text;
using System.Text.RegularExpressions;

namespace libntregsharp
{
	public class ValueKey : IKey
	{
		private Regex _regex;
		
		private List<IKey> _subkeys; 
		
		public ValueKey ()
		{
			
			
			
		}
		
		public ValueKey(int index, byte[] hive)
		{
					//the lengths we will be working with.
			int word = 2;
			int dword = word+word; //double word
			int qword = dword+dword; //quad word
			
			
            int nameLength = 0;
            int dataLength = 0;
            int dataOffset = 0;
            ValueType vt = (ValueType)0;
            bool hasName = true;
			
			this.OffsetFromZero = index;
			Console.WriteLine("\r\nOffset from zeroth byte: " + index.ToString());
			
			ASCIIEncoding enc = new ASCIIEncoding();
			
			//Get name length
			
			//hive[index+(int)0x0048]
			
			byte[] lb = new byte[dword]; //should only be a word length. not sure why I need to make this dword
					
			for (int k = 0;k<word;k++)
			{
				lb[k] = hive[index+(int)0x0002+k];
			}
					
			nameLength = BitConverter.ToInt32(lb, 0);
			
			
			int keyLength = 1024+nameLength;
			byte[] bs = new byte[keyLength];
			
			for (int k = 0; k < keyLength;k++)
			{
				bs[k] = hive[index+k];
			}
			
			
			for (int i = 0;i<bs.Length;)
			{
				if (i == (int)0x0000)
				{
					if ((char)bs[0] != 'v' || (char)bs[1] != 'k')
					{
						throw new Exception("Bad header");
					}
					
					i+= word;
				}
				else if (i == (int)0x0002)
				{
//					byte[] bytes = new byte[dword];
//					
//					for (int k = 0;k<word;k++)
//					{
//						bytes[k] = bs[i+k];
//					}
//					
//					nameLength = BitConverter.ToInt32(bytes, 0);
//					
//					Console.WriteLine("Name length: " + nameLength.ToString());
					
					i += word;
				}
				else if (i == (int)0x0004)
				{
					byte[] bytes = new byte[dword];
					
					for (int k = 0;k<dword;k++)
					{
						bytes[k] = bs[i+k];
					}
					
					dataLength = BitConverter.ToInt32(bytes, 0);
					
					Console.WriteLine("Data length: " + dataLength.ToString());
					
					i += dword;
				}
				else if (i == (int)0x0008)
				{
					byte[] bytes = new byte[dword];
					
					for (int k = 0;k<dword;k++)
					{
						bytes[k] = bs[i+k];
					}
					
					dataOffset = BitConverter.ToInt32(bytes, 0);
					
					Console.WriteLine("Data offset: " + dataOffset.ToString());
					
					i += dword;
				}
				else if (i == (int)0x000C)
				{
					byte[] bytes = new byte[dword];
					
					for (int k = 0;k<dword;k++)
					{
						bytes[k] = bs[i+k];
					}
					
					vt = (ValueType)BitConverter.ToInt32(bytes, 0);
					
					Console.WriteLine("Value type: " + vt.ToString());
					
					i += dword;
				}
				else if (i == (int)0x0010)
				{	
					hasName = false; //which of these is more likely?? I should look into this.
					
					if (bs[i] != (byte)0x00)
					{
						hasName = true;
					}
					
					Console.WriteLine("Has name: " + (hasName ? "yes" : "no"));
					
					i += word;
				}
				else if (i == (int)0x0012) ///trash
				{
					i += word;
				}
				else if (i == (int)0x0014)
				{
					if (hasName)
					{
						char[] name = new char[nameLength];
						
						for (int k = 0;k<nameLength;k++)
						{
							name[k] = (char)bs[i+k];
						}
						
						string n = new string(name);
						Console.WriteLine("Name: " + n);
					}
					else
					{
						Console.WriteLine("Name: Default");
					}
					
					i += bs.Length - i; //done
				}
				else i+= word;
				
			}
		}
		
		public int OffsetFromZero { get; set; }
		
		public Regex Regex 
		{
			get
			{
				if (_regex == null)
					_regex = new Regex (@"vk.{3}\x00\x00[\x00|\x80]");
				
				return _regex;
			}
		}
		
		public string KeyName { get; private set; }
		
		public List<IKey> Subkeys 
		{ 
			get
			{
				if (_subkeys == null)
					_subkeys = new List<IKey>();
				
				return _subkeys;
			}
			private set
			{
				_subkeys = value;
			}
		}
		
	}
}

